package com.ttjj.entity.map;

import com.alibaba.fastjson.annotation.JSONField;
import com.ttjj.common.Constants;
import com.ttjj.enums.EnumDirection;

import java.text.MessageFormat;

/**
 * 像素坐标对象
 */
public class Coordinate {
    protected final int x;
    protected final int y;
    @JSONField(
            serialize = false
    )
    protected final int hash;

    public Coordinate(int x, int y) {
        this.x = x;
        this.y = y;
        this.hash = y * 1400 + x;
    }

    public EnumDirection getVerticalDirectFrom(Coordinate cod) {
        if (this.y < cod.y) {
            return EnumDirection.TOP;
        } else {
            return this.y > cod.y ? EnumDirection.DOWN : EnumDirection.STOP;
        }
    }

    public EnumDirection getHorizontalDirectFrom(Coordinate cod) {
        if (this.x < cod.x) {
            return EnumDirection.LEFT;
        } else {
            return this.x > cod.x ? EnumDirection.RIGHT : EnumDirection.STOP;
        }
    }

    public Coordinate stepByDirect(EnumDirection direct, int stepSize) {
        if (direct == EnumDirection.TOP) {
            return new Coordinate(this.x, this.y - stepSize);
        } else if (direct == EnumDirection.DOWN) {
            return new Coordinate(this.x, this.y + stepSize);
        } else if (direct == EnumDirection.LEFT) {
            return new Coordinate(this.x - stepSize, this.y);
        } else {
            return direct == EnumDirection.RIGHT ? new Coordinate(this.x + stepSize, this.y) : this;
        }
    }

    public Coordinate getTopLeftCod(int radius) {
        return new Coordinate(this.x - radius + 1, this.y - radius + 1);
    }

    public Coordinate getTopRightCod(int radius) {
        return new Coordinate(this.x + radius - 1, this.y - radius + 1);
    }

    public Coordinate getDownLeftCod(int radius) {
        return new Coordinate(this.x - radius + 1, this.y + radius - 1);
    }

    public Coordinate getDownRightCod(int radius) {
        return new Coordinate(this.x + radius - 1, this.y + radius - 1);
    }

    public Coordinate getTopCod(int radius) {
        return new Coordinate(this.x, this.y - radius + 1);
    }

    public Coordinate getDownCod(int radius) {
        return new Coordinate(this.x, this.y + radius - 1);
    }

    public Coordinate getLeftCod(int radius) {
        return new Coordinate(this.x - radius + 1, this.y);
    }

    public Coordinate getRightCod(int radius) {
        return new Coordinate(this.x + radius - 1, this.y);
    }

    public Position toPosition() {
        return new Position(this.y / 50, this.x / 50);
    }

    /**
     * 判断是否撞车
     */
    public boolean isCrashWith(Coordinate otherCoordinate) {
        Position position = otherCoordinate.toPosition();
        if (position.hash == this.toPosition().hash) {
            return true;
        }
        int radius = Constants.getCommonLen() / 2;

        // 我的范围
        int meSmallX = this.x - radius;
        int meBigX = this.x + radius;
        int meSmallY = this.y - radius;
        int meBigY = this.y + radius;

        // 敌方范围
        int otherSmallX = otherCoordinate.x - radius;
        int otherBigX = otherCoordinate.x + radius;
        int otherSmallY = otherCoordinate.y - radius;
        int otherBigY = otherCoordinate.y + radius;

        return ((otherSmallX > meSmallX && otherSmallX < meBigX)
                || (otherBigX > meSmallX && otherBigX < meBigX)
                || (otherSmallX == meSmallX && otherBigX == meBigX)) &&
                ((otherSmallY > meSmallY && otherSmallY < meBigY)
                        || (otherBigY > meSmallY && otherBigY < meBigY)
                        || (otherSmallY == meSmallY && otherBigY == meBigY));
    }

    /**
     * 判断敌方位置是否在我下一步的移动方向上
     * 以此来判断我是否为主动撞击方
     */
    public boolean isMyActiveCrash(Coordinate otherCoordinate, EnumDirection meNextDirection) {
        if (meNextDirection == EnumDirection.TOP) {
            return otherCoordinate.getY() <= this.getY();
        } else if (meNextDirection == EnumDirection.DOWN) {
            return otherCoordinate.getY() >= this.getY();
        } else if (meNextDirection == EnumDirection.LEFT) {
            return otherCoordinate.getX() <= this.getX();
        } else if (meNextDirection == EnumDirection.RIGHT) {
            return otherCoordinate.getX() >= this.getX();
        }

        return false;
    }

    public String print() {
        return MessageFormat.format("({0},{1})", this.x, this.y);
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        } else if (obj != null && this.getClass() == obj.getClass()) {
            Coordinate other = (Coordinate) obj;
            return this.hash == other.hash;
        } else {
            return false;
        }
    }

    public int hashCode() {
        return this.hash;
    }

    public int getX() {
        return this.x;
    }

    public int getY() {
        return this.y;
    }

    public int getHash() {
        return this.hash;
    }

    public String toString() {
        return "Coordinate(x=" + this.getX() + ", y=" + this.getY() + ", hash=" + this.getHash() + ")";
    }
}
